﻿#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
/*********************14.深入理解指针4************************/
/*******1.字符指针变量*******/
//int main()
//{
//	//char ch = 'w';
//	//char* p = &ch; //p指向一个字符变量
//
//	//char arr[10] = "abcdef"; //字符数组中可以存放字符串，字符数组内容可以修改
//	//char* p = arr; //p指向一个字符数组
//	//printf("%s\n", arr);
//	//printf("%s\n", p);
//
//	//const char* p = "abcdef"; //常量字符串，和数组非常相似，也是一个连续空间中存放了多个字符，但是常量字符串的内容不可修改
//	////这次赋值是将字符串首字符a的地址付给p
//	//
//	////*p ='w'; 这种是错误的不能修改
//
//	//printf("%c ", *p);
//	  
//	return 0;
//}

//int main()
//{
//	char str1[] = "hello bit.";
//	char str2[] = "hello bit.";
//	const char* str3 = "hello bit.";
//	const char* str4 = "hello bit.";
//
//	if (str1 == str2) //比较的数组的首元素的地址
//		printf("str1 and str2 are same\n");
//	else
//		printf("str1 and str2 are not same\n");
//
//	if (str3 == str4) //比较的是两个指针变量中存放的地址
//		printf("str3 and str4 are same\n");
//	else
//		printf("str3 and str4 are not same\n");
//
//	return 0;
//}

/*******2.数组指针变量*******/
//字符指针变量 char* p;存放字符变量的地址 -指向字符变量的指针
//整形指针变量 int* p;存放整形变量的地址 -指向整形变量的指针
//数组指针变量 存放数组的地址 - 指向数组的指针

//int man()
//{
//	int arr[5] = { 0 };
//
//	int(*p) [5] = &arr;//取出数组的地址
//	//p是数组指针变量
//	return 0;
//}

//int main()
//{
//	/*char arr[8];
//	char (*pc) [8] = &arr;*/
//·
//	char* arr[7];
//	char* (*pc)[7] = &arr;
//
//	return 0;
//}

//指针数组-数组，里面存放的是指针
//char* arr[5];
//int*  arr[6];

//数组指针 - 指针，指向数组的指针，存放的是数组的地址
//字符指针char* p; 存放字符的地址，可以指向字符
//整形指针int* p; 存放整型的地址，可以指向整型

//int arr[6] = { 0 };
//int (*p) [6] = &arr;
//p就是数组指针变量；类型是int(*)[6]

//int main()
//{
//	int arr[6] = { 1,2,3,4,5,6 };
//	int (*p)[6] = &arr;
//
//	int i = 0;
//	for (i = 0; i < 6; i++)
//	{
//		printf("%d ",(*p)[i]);
//	}
//	return 0;
//}

/*******3.⼆维数组传参的本质*******/

//void Printf(int arr[3][5],int r,int c)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < r; i++)
//	{
//		for (j = 0; j <c; j++)
//		{
//			printf("%d ",arr [i][j]);
//		}
//		printf("\n");
//	}
//}

//void Printf(int (*arr)[5], int r, int c)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < r; i++)
//	{
//		for (j = 0; j < c; j++)
//		{
//			printf("%d ", arr[i][j]);
//		}
//		printf("\n");
//	}
//}
//int main()
//{
//	int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7} };
//
//	//写一个函数打印arr数组
//	Printf(arr, 3 , 5);
//	return 0;
//}

/*******4.函数指针变量*******/
//字符指针指向字符，存储字符的地址
//整形指针指向整型，存储整形的地址
//数组指针指向数组，存储数组的地址
//函数指针指向函数，存储函数的地址

//int Add(int x, int y)
//{
//	return x + y;
//}
//int main()
//{
//	/*int i = 10;
//	int j = 20;
//	int r = Add(i, j);
//	printf("%d", r);*/
//
//	//int (*pf)(int x, int y)= &Add;//pf就是函数指针变量
//	int (*pf)(int, int ) = &Add;
//
//	int r = (*pf)(15, 15);
//	printf("%d",r);
//
//	//printf("%p ",&Add);//函数的地址
//	//printf("%p ", Add);//两个相同
//
//	return 0;
//}

//int Add(int x, int y)
//{
//	return x + y;
//}
//int main()
//{
//	int i = 10;
//	int j = 20;
//
//	int (* pf)(int, int) = Add;
//	//int (*)(int, int)函数指针类型
//	//pf == Add
//	// 
//    int r = (*pf)(i, j);
//	//int r = (pf)(i, j);
//	//int r = pf(i, j);
//	printf("%d\n", r);
//
//	return 0;
//}

//void (*p)();//函数指针变量
//void (*)() //函数指针类型
//(int)3.14 //强制类型转换

//出自《c陷阱和缺陷》
//int main()
//{
//	( *( void (*)() )0 )();//函数调用
//	//1.将0这个整数强制转换成函数指针类型
//	//2.去调用0地址处的这个函数
//
//	return 0;
//}

//void (*signal(int, void(*)(int)))(int);//函数声明
////函数名字signal
////signal函数的参数有2个，第一个是int类型，第二个是函数指针void(*)(int)类型，这个函数指针指向的函数有一个int参数，返回类型是void
////signal函数的返回值类型也是一个函数指针类型：void(*)(int)，这个函数指针指向的函数有一个int参数，返回类型是void

/* 4.2 typedef 关键字*/
//typedef 是⽤来类型重命名的，可以将复杂的类型，简单化

//unsigned int num;
//typedef unsigned int uint;
//
//int main()
//{
//	unsigned int num;
//	uint num2;
//
//	return 0;
//}

//typedef int* ptf_t;
//
//int main()
//{
//	//int* p1;
//	//ptf_t p2;//这两个相同
//
//	//int* p1, p2;
//	//ptf_t p3, p4;//这样p2是int类型
//
//	//int* p1, *p2;
//	//ptf_t p3, p4;//这样才都是int*类型
//
//	return 0;
//}

//typedef void (*pf_t)(char, int);//将void (*)(char, int)函数指针类型重命名为pf_t
//
//int main()
//{
//	void (*p)(char, int);//p是函数指针变量
//	pf_t p2;
//
//	return 0;
//}

//typedef int(*pf_t)[5];//将int(*)[5]数组指针类型重命名为：pf_t
//
//int main()
//{
//	int arr[5] = { 1,2,3,4,5 };
//	int(*p1)[5] = &arr; //p1是数组指针变量
//	pf_t p2;
//
//	return 0;
//}

//简化void (*signal(int, void(*)(int)))(int);
//typedef void(*pf_t)(int);
//
//int mian()
//{
//	void (*signal(int, void(*)(int)))(int);
//	pf_t signal(int, pf_t);
//	return 0;
//}

/*******5.函数指针数组*******/
//指针数组
//char* arr[5];//字符指针数组
//int* arr[5]; //整形指针数组
//函数指针数组是数组
//这种数组中存放的都是函数的地址

//int Add(int x, int y)
//{
//	return (x + y);
//}
//
//int Sub(int x, int y)
//{
//	return (x - y);
//}
//
//int main()
//{
//	int (*pf1)(int, int) = Add;
//	int (*pf2)(int, int) = Sub;
//
//	//int (*pa[4])(int, int);//函数指针数组
//
//	int (*arr[4])(int, int) = {Add , Sub};
//	//int r = (*arr[1])(1,2);
//	int r = arr[0](1, 2);
//
//	printf("%d ", r);
//	return 0;
//}

/*******6. 转移表*******/
//函数指针数组的⽤途：转移表

//写一个简易计算器
//实现加减乘除
//不需要退出程序，可以继续计算

//void mean()
//{
//	printf("*************************\n");
//	printf("*****1.Add*****2.Sub*****\n");
//	printf("*****3.Mul*****4.Div*****\n");
//	printf("*******0.退出计算********\n");
//	printf("*************************\n");
//
//}
//int Add(int x, int y)
//{
//	return (x + y);
//}
//
//int Sub(int x, int y)
//{
//	return (x - y);
//}
//
//int Mul(int x, int y)
//{
//	return (x * y);
//}
//
//int Div(int x, int y)
//{
//	return (x / y);
//}
//
//int main()
//{
//	int input = 0;
//	do
//	{
//		mean();
//		printf("请选择：");
//		scanf("%d", &input);
//		int a = 0;
//		int b = 0;
//		int r = 0;
//		switch (input)
//		{
//		case 1:
//			printf("请输入2个操作数：");
//			scanf("%d %d",&a ,&b);
//			r = Add(a, b);
//			printf("r = %d\n", r);
//			break;
//		case 2:
//			printf("请输入2个操作数：");
//			scanf("%d %d", &a, &b);
//			r = Sub(a, b);
//			printf("r = %d\n", r);
//			break;
//		case 3:
//			printf("请输入2个操作数：");
//			scanf("%d %d", &a, &b);
//			r = Mul(a, b);
//			printf("r = %d\n", r);
//			break;
//		case 4:
//			printf("请输入2个操作数：");
//			scanf("%d %d", &a, &b);
//			r = Div(a, b);
//			printf("r = %d\n", r);
//			break;
//		case 0:
//			printf("退出计算\n");
//			break;
//		default:
//			printf("输入错误，请重新输入\n");
//			break;
//
//		}
//	} while (input);
//	return 0;
//}



//void mean()
//{
//	printf("*************************\n");
//	printf("*****1.Add*****2.Sub*****\n");
//	printf("*****3.Mul*****4.Div*****\n");
//	printf("*******0.退出计算********\n");
//	printf("*************************\n");
//
//}
//int Add(int x, int y)
//{
//	return (x + y);
//}
//
//int Sub(int x, int y)
//{
//	return (x - y);
//}
//
//int Mul(int x, int y)
//{
//	return (x * y);
//}
//
//int Div(int x, int y)
//{
//	return (x / y);
//}
//
//int main()
//{
//	int input = 0;
//	do
//	{
//		mean();
//		printf("请选择：");
//		scanf("%d", &input);
//		int a = 0;
//		int b = 0;
//		int r = 0;
//		int (*arr[5])(int, int) = { NULL,Add,Sub,Mul,Div };
//		
//		if (input > 0 && input < 5)
//		{
//			printf("请输入2个操作数：");
//			scanf("%d %d", &a, &b);
//			r = arr[input](a, b);
//			printf("r = %d\n", r);
//		}
//		else if (input == 0)
//		{
//			printf("退出计算\n");
//		}
//		else
//			printf("输入错误，请重新输入\n");
//		
//	} while (input);
//	return 0;
//}















